﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.MetadirectoryServices;
using Lithnet.GoogleApps;
using Lithnet.GoogleApps.MA;
using Lithnet.GoogleApps.Api;
using Lithnet.GoogleApps.ManagedObjects;
using System.Collections.ObjectModel;
using System.Diagnostics;
using Microsoft.MetadirectoryServices.DetachedObjectModel;
using Lithnet.MetadirectoryServices;

namespace Lithnet.GoogleApps.MA.UnitTests
{
    public static class UnitTestCore
    {
        private static bool hasInitialized;

        private static UnitTestParameters config;

        private static Schema schema;

        public static void Initialize()
        {
            if (!hasInitialized)
            {
                UnitTestCore.config = new UnitTestParameters();
                ConnectionPools.InitializePools(UnitTestCore.config.Credentials, 5, 5);
                UnitTestCore.schema = ManagementAgentSchema.GetSchema(UnitTestCore.config);
                GroupMembership.GetInternalDomains(UnitTestCore.config.CustomerID);
                hasInitialized = true;
            }
        }

        public static Schema Schema
        {
            get
            {
                return UnitTestCore.schema;
            }
        }

        public static UnitTestParameters Config
        {
            get
            {
                return UnitTestCore.config;
            }
        }

        public static void DeleteUser(string key)
        {
            try
            {
                UserRequestFactory.Delete(key);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception: {0}", ex.Message);
            }
        }

        public static void DeleteGroup(string key)
        {
            try
            {
                GroupRequestFactory.Delete(key);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception: {0}", ex.Message);
            }
        }

        public static void ReloadSchema()
        {
            UnitTestCore.schema = ManagementAgentSchema.GetSchema(UnitTestCore.config);
        }

        private static GoogleJsonSerializer serializer = new GoogleJsonSerializer();

        public static string Serialize(object o)
        {
            return serializer.Serialize(o);
        }

        public static void PutCSEntryAndThrowOnError(CSEntryChange csentry)
        {
            CSEntryChangeResult result = CSEntryChangeFactory.PutCSEntryChange(csentry, UnitTestCore.Config, UnitTestCore.Schema.Types["user"]);

            if (result.ErrorCode != MAExportError.Success)
            {
                throw new Exception(result.ErrorName);
            }

            System.Threading.Thread.Sleep(1000);
        }

        public static string CreateUser()
        {
            CSEntryChangeDetached csentry = new CSEntryChangeDetached(Guid.NewGuid(), ObjectModificationType.Unconfigured, MAImportError.Success, null);
            csentry.DN = string.Format("{0}@{1}", Guid.NewGuid().ToString(), Properties.Settings.Default.TestDomainSuffix);
            csentry.ObjectModificationType = ObjectModificationType.Add;
            csentry.ObjectType = "user";

            IList<object> aliases = new List<object>() 
                {
                    string.Format("{0}@{1}", Guid.NewGuid().ToString(), Properties.Settings.Default.TestDomainSuffix),
                    string.Format("{0}@{1}", Guid.NewGuid().ToString(), Properties.Settings.Default.TestDomainSuffix)
                };

            csentry.CreateAttributeAdd("name_givenName", "test3");
            csentry.CreateAttributeAdd("name_familyName", "test4");
            csentry.CreateAttributeAdd("suspended", true);
            csentry.CreateAttributeAdd("includeInGlobalAddressList", false);
            csentry.CreateAttributeAdd("orgUnitPath", "/");
            csentry.CreateAttributeAdd("notes_value", "my notes 2");
            csentry.CreateAttributeAdd("notes_contentType", "text_html");
            csentry.CreateAttributeAdd("primaryEmail", csentry.DN);
            csentry.CreateAttributeAdd("aliases", aliases);

            return csentry.DN;
        }
    }
}
